package tree

// Convert 复制树 从 S 类型复制到 T 类型
// 使用示例
// node := Convert(nil, node, func(s *model.PageTree) []*model.PageTree {
// 	return s.Children
// }, func(parent *pb.MenuNode, child *model.PageTree) *pb.MenuNode {
// 	parentName := ""
// 	if parent != nil {
// 		parentName = parent.Name
// 	}
// 	node := child.AsMenuNode(parentName)
// 	if parent != nil {
// 		parent.Children = append(parent.Children, node)
// 	}
// 	return node
// })
// func Convert[T any, S any](parent *T, source *S,
// 	getChildren func(*S) []*S,
// 	copyObject func(parent *T, child *S) *T) *T {
// 	target := copyObject(parent, source)
// 	children := getChildren(source)
// 	for _, child := range children {
// 		Convert(target, child, getChildren, copyObject)
// 	}
// 	return target
// }

type TreeAble interface {
	GetChildren() []interface{}
}

func Convert[T any, S TreeAble](parent T, source S,
	set func(parent T, child S) T) T {
	target := set(parent, source)
	for _, child := range (source).GetChildren() {
		Convert(target, child.(S), set)
	}
	return target
}

func Traversal[T TreeAble](node T, callback func(T) error) error {
	if err := callback(node); err != nil {
		return err
	}
	for _, c := range (node).GetChildren() {
		if err := Traversal(c.(T), callback); err != nil {
			return err
		}
	}
	return nil
}

// Traversal2 遍历树节点时，带 parent 信息
// 调用时 parent 可以是 nil
func Traversal2[T TreeAble](parent, node T, callback func(parent, node T) error) error {
	if err := callback(parent, node); err != nil {
		return err
	}
	for _, c := range (node).GetChildren() {
		if err := Traversal2(node, c.(T), callback); err != nil {
			return err
		}
	}
	return nil
}

// // Traversal  遍历树节点
// func Traversal[V any, T TreeAble[V]](
// 	node *T,
// 	callback func(*V) error) error {
// 	if err := callback(T.Value()); err != nil {
// 		return err
// 	}
// 	for _, child := range (*node).Children() {
// 		if err := Traversal(child, callback); err != nil {
// 			return err
// 		}
// 	}
// 	return nil
// }
